package com.icow.wms.basic.domain;

import com.icow.wms.basic.utils.LiftHandler;
import com.icow.wms.basic.utils.OpenTcs;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@Data
@NoArgsConstructor
@AllArgsConstructor
@SuppressWarnings("all")
@Slf4j
public class Lift implements Runnable {
    private String callLiftCommand;
    private String liftReachCommand;
    private String stopCallLiftCommand;
    private boolean liftReachOne;
    private boolean liftReachTwo;
    private boolean liftReachThree;
    private boolean liftReachFour;
    private String closeLiftPosition;
    private String vehicleName;
    private String floor;

    private String ip;

    public Lift(String ip) {
        this.ip = ip;
    }

    public void init(String callLiftCommand, String liftReachCommand, String stopCallLiftCommand, String floor) {
        this.callLiftCommand = callLiftCommand;
        this.liftReachCommand = liftReachCommand;
        this.stopCallLiftCommand = stopCallLiftCommand;
        this.floor = floor;
        clearDoorState();//电梯状态初始化
    }

    public void canClearLiftState() {
        accessed.set(false);
        liftReachOne = false;//电梯状态置为false
        liftReachTwo = false;
        liftReachThree = false;
        liftReachFour = false;
    }

    private AtomicBoolean accessed = new AtomicBoolean(false);

    public void clearDoorState() {
        if (!accessed.getAndSet(true)) {
            liftReachOne = false;
            liftReachTwo = false;
            liftReachThree = false;
            liftReachFour = false;
        }
    }

    public boolean equals(byte[] readBytes, byte[] liftReachBytes) {
        if (readBytes.length != liftReachBytes.length) {
            return false;
        }
        for (int i = 0; i < readBytes.length; i++) {
            if (readBytes[i] != liftReachBytes[i]) {
                System.out.println(i + " not equals " + readBytes[i]);
                return false;
            }
        }
        return true;
    }

    public byte[] getBytesForLift(String callLiftCommand) {
        String[] hexValues = callLiftCommand.split(" ");
        List<Byte> byteList = new ArrayList<>();
        for (String hex : hexValues) {
            if (!hex.isEmpty()) {
                byteList.add((byte) Integer.parseInt(hex, 16));
            }
        }
        byte[] bytes = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            bytes[i] = byteList.get(i);
        }
        return bytes;
    }

    public boolean callLift(String ip, String callLiftCommand) {
        byte[] cmdMsgForLift = getBytesForLift(callLiftCommand);
        boolean callLift = LiftHandler.sendMsg(ip, cmdMsgForLift);
        return callLift;
    }

    public boolean stopCallLift(String ip, String stopCallLiftCommand) {
        byte[] cmdMsgForLift = getBytesForLift(stopCallLiftCommand);
        boolean stopCallLift = LiftHandler.sendMsg(ip, cmdMsgForLift);
        return stopCallLift;
    }

    public boolean readLiftState(String ip, String readLiftReachCommand, int floor) {
        byte[] readLiftBytes = getBytesForLift(readLiftReachCommand);
        boolean reachLift = LiftHandler.sendMsg(ip, readLiftBytes);
        if (!reachLift) {
            log.error("lift read error");
            return false;
        }
        if (floor == 1) {
            return liftReachOne;
        } else if (floor == 2) {
            return liftReachTwo;
        } else if (floor == 3) {
            return liftReachThree;
        } else if (floor == 4) {
            return liftReachFour;
        }
        log.error("lift read floor error");
        return false;
    }

    @Override
    public void run() {
        int liftCase = 1;
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (ip == null) {
                log.info("ip is null");
                return;
            }
            switch (liftCase) {
                case 1:
                    String vehiclePosition = OpenTcs.getVehiclePosition(vehicleName);
                    boolean callLift = callLift(ip, callLiftCommand);
                    if (callLift && closeLiftPosition.equals(vehiclePosition)) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (stopCallLiftCommand == null || stopCallLiftCommand.equals("")) {
                            log.info("stopCallLiftCommand is null just return");
                            return;
                        } else if (stopCallLift(ip, stopCallLiftCommand)) {
                            log.info(vehicleName + " arrive closeLiftPosition " + closeLiftPosition + " closeLift");
                            return;
                        }
                    }
                    break;
            }
        }
    }


}
